package org.example.translate;

import java.util.Queue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.RejectedExecutionException;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;

public class TranslateActivity extends Activity {	
	private Spinner fromSpinner;
	private Spinner toSpinner;
	private EditText origText;
	private TextView transText;
	private TextView retransText;
	
	private TextWatcher textWatcher;
	private OnItemSelectedListener itemListener;
	
	private Handler guiThread;
	private ExecutorService transThread;
	private Runnable updateTask;
	private Future transPending;
	
	
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        initThreading();
        findViews();
        setAdapters();
        setListeners();
    }


	private void setListeners() {
		// TODO Auto-generated method stub
		// define event listeners
		textWatcher = new TextWatcher() {
			
			@Override
			public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
				// TODO Auto-generated method stub
				// do nothing
			}
			
			@Override
			public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
					int arg3) {
				// TODO Auto-generated method stub
				queueUpdate(1000); // milliseconds
			}					

			@Override
			public void afterTextChanged(Editable arg0) {
				// TODO Auto-generated method stub
				
			}
		};
		
		itemListener = new OnItemSelectedListener() {				

			@Override
			public void onItemSelected(AdapterView parent, View view,
					int position, long id) {
				// TODO Auto-generated method stub
				queueUpdate(200);
			}

			@Override
			public void onNothingSelected(AdapterView<?> arg0) {
				// TODO Auto-generated method stub
				
			}
		}; 
		
		// set graphical user interface listeners
		origText.addTextChangedListener(textWatcher);
		fromSpinner.setOnItemSelectedListener(itemListener);
		toSpinner.setOnItemSelectedListener(itemListener);		
	}
	
	private void queueUpdate(int i) {
		// TODO Auto-generated method stub
		
	}


	private void setAdapters() {
		// TODO Auto-generated method stub
		// spinner list comes from resource
		// spinner user interface uses standard layouts
		ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
																this, 
																R.array.languages, 
																android.R.layout.simple_spinner_item);
		adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
		fromSpinner.setAdapter(adapter);
		toSpinner.setAdapter(adapter);
		
		// automatically select 2 spinner items
		fromSpinner.setSelection(8); // english
		toSpinner.setSelection(11); // french
	}


	private void initThreading() {
		// TODO Auto-generated method stub
		guiThread = new Handler();
		transThread = Executors.newSingleThreadExecutor();
		// this task will translate and update the screen.
		updateTask = new Runnable() {
			
			@Override
			public void run() {
				// TODO Auto-generated method stub
				
				// get text to translate
				String original = origText.getText().toString().trim();
				
				// cancel previous translation if there was one.
				if(transPending != null)
				{
					transPending.cancel(true);
				}
				
				// take care of easy case
				if(original.length() == 0)
				{
					transText.setText(R.string.empty);
					retransText.setText(R.string.empty);
				}else{
					// let user know we're doing
					transText.setText(R.string.translating);
					retransText.setText(R.string.translating);
					
					// begin to translate now but don't wait for it
					try {
						TranslateTask translateTask = new TranslateTask(
															TranslateActivity.this, // reference to activity
															original, // original text
															getLang(fromSpinner), // from language
															getLang(toSpinner) // to language
															);
						
					} catch (RejectedExecutionException e) {
						// TODO: handle exception
						transText.setText(R.string.translation_error);
						retransText.setText(R.string.translation_error);
					}
				}
			}

			
		};
	}

	/**
	 * Extract language code from current spinner item
	 * @param spinner
	 * @return
	 */
	private String getLang(Spinner spinner) {
		// TODO Auto-generated method stub
		String result = spinner.getSelectedItem().toString();
		int lparen = result.indexOf('(');
		int rparen = result.indexOf(')');
		result = result.substring(lparen+1, rparen);
		return result;
	}
	
	/**
	 * Request an update to start after a short delay
	 * @param delayMillis
	 */
	private void queueUpdate(long delayMillis)
	{
		// cancel the previous
		guiThread.removeCallbacks(updateTask);
		// start an update if nothing happens after a few milliseconds
		guiThread.postDelayed(updateTask, delayMillis);
	}
	
	public void setTranslated(String text)
	{
		guiSetText(transText, text);
	}
	
	public void setRetranslated(String text)
	{
		guiSetText(retransText, text);
	}
	
	/**
	 * All changes of GUI must be done in GUI thread
	 * @param view
	 * @param text
	 */
	private void guiSetText(final TextView view, final String text)
	{
		guiThread.post(new Runnable() {
			
			@Override
			public void run() {
				// TODO Auto-generated method stub
				view.setText(text);
			}
		});
	}
	
	private void findViews() {
		// TODO Auto-generated method stub
		fromSpinner = (Spinner)findViewById(R.id.from_language);
		toSpinner = (Spinner)findViewById(R.id.to_language);
				
		origText = (EditText)findViewById(R.id.original_text);
		transText = (TextView)findViewById(R.id.translated_text);
		retransText = (TextView) findViewById(R.id.retranslated_text);
	}
	
}